﻿using Autodesk.AutoCAD.ApplicationServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PublicClass.CadWatch
{
    /// <summary>
    /// DocumentCollection 事件 – 对文档的创建与销毁、成为活动文档或进入非活动状态、以及文档的锁定模式发生变化等作出反应。
    /// </summary>
    public class CadDocumentCollectionWatch
    {
        // 所有文档存储下来
        private Dictionary<Document, CadDocumentWatch> DocToWatch = new Dictionary<Document,CadDocumentWatch>();
        public CadDocumentCollectionWatch()
        {
            DocumentCollection docCollection = Application.DocumentManager;

            // 当前文档处理
            DoDocWatch(null);

            docCollection.DocumentCreated += DocumentCollection_Created;
            docCollection.DocumentDestroyed += DocumentDestroyed;
            docCollection.DocumentToBeActivated += DocumentCollection_ToBeActivated;
            docCollection.DocumentActivated += DocumentCollection_ToActivated;
            docCollection.DocumentToBeDeactivated += DocumentCollection_ToBeDeactivated;
        }

        ~CadDocumentCollectionWatch()
        {
            DocToWatch = null; // 回收所有文档反应器

            DocumentCollection docCollection = Application.DocumentManager;

            docCollection.DocumentCreated -= DocumentCollection_Created;
            docCollection.DocumentDestroyed -= DocumentDestroyed;
            docCollection.DocumentToBeActivated -= DocumentCollection_ToBeActivated;
            docCollection.DocumentActivated -= DocumentCollection_ToActivated;
            docCollection.DocumentToBeDeactivated -= DocumentCollection_ToBeDeactivated;

        }
        /// <summary>
        /// 文档操作类型
        /// </summary>
        enum DocType
        {
            eCreated = 0,
            eActive,
            eDestroyed,
            eDeactivated,
        }
        /// <summary>
        /// 文档操作反应函数
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="type"></param>
        private void DoDocWatch(Document doc, DocType type = DocType.eActive)
        {
            if (null == doc)
                doc = CadUnits.CurDoc();

            if (null == doc)
                return;

            if (DocToWatch.ContainsKey(doc))
            {
                if (type == DocType.eDestroyed || type == DocType.eDeactivated)
                    DocToWatch.Remove(doc);
                else
                    DocToWatch[doc].ActiveDoc();
            }
            else
            {
                if (type == DocType.eCreated || type == DocType.eActive)
                {
                    DocToWatch.Add(doc, new CadDocumentWatch(doc));
                }
            }
        }

        /// <summary>
        /// 文档创建成功时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DocumentCollection_Created(object sender, DocumentCollectionEventArgs e)
        {
            if (e.Document == null)
                return;

            CadUnits.WriteMessage("\n创建文档了<{0}>", e.Document.Name);

            DoDocWatch(e.Document, DocType.eCreated);  
        }
        /// <summary>
        /// 文档被激活时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DocumentCollection_ToBeActivated(object sender, DocumentCollectionEventArgs e)
        {
            if (e.Document == null)
                return;

            CadUnits.WriteMessage("\n文档被激活了<{0}>", e.Document.Name);
            DoDocWatch(e.Document, DocType.eActive);
        }
        /// <summary>
        /// 文档激活时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DocumentCollection_ToActivated(object sender, DocumentCollectionEventArgs e)
        {
            if (e.Document == null)
                return;

            CadUnits.WriteMessage("\n文档激活了<{0}>", e.Document.Name);
            DoDocWatch(e.Document, DocType.eActive);
        }

        /// <summary>
        /// 文档无效时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DocumentCollection_ToBeDeactivated(object sender, DocumentCollectionEventArgs e)
        {
            if (e.Document == null)
                return;

            CadUnits.WriteMessage("\n文档无效时");
            DoDocWatch(e.Document, DocType.eDeactivated);
        }
        /// <summary>
        /// 文档销毁时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DocumentDestroyed(object sender, DocumentDestroyedEventArgs e)
        {
            CadUnits.WriteMessage("\n文档销毁了");
            // DoDocWatch(e.FileName, DocType.eDestroyed);
        }

    }
    /// <summary>
    /// Document 事件 – 对关闭图形、运行 AutoCAD 命令、运行 AutoLISP 命令或函数、修改系统变量等作出反应。
    /// </summary>
    public class CadDocumentWatch
    {
        private Document Doc = null;
        private CadDataBaseWatch DbWatch = null;
        public CadDocumentWatch(Document doc)
        {
            Doc = doc;
            if (null == doc)
                doc = CadUnits.CurDoc();

            InitDocWatch();
        }

        ~CadDocumentWatch()
        {
            UnInitDocWatch();
        }

        void InitDocWatch()
        {
            if (Doc == null)
                return;
            Doc.CommandWillStart += CommandEvent_WillStart;     // 命令开始
            Doc.CommandEnded += CommandEvent_CommandEnd;        // 命令结束
            Doc.CommandCancelled += CommandEvent_CommandCancelled;       // 取消的命令
            Doc.CommandFailed += CommandEvent_CommandFailed;       // 失败的命令

            DbWatch = new CadDataBaseWatch(Doc.Database);
        }

        void UnInitDocWatch()
        {
            Doc.CommandWillStart -= CommandEvent_WillStart;     // 命令开始
            Doc.CommandEnded -= CommandEvent_CommandEnd;        // 命令结束
            Doc.CommandCancelled -= CommandEvent_CommandCancelled;       // 取消的命令
            Doc.CommandFailed -= CommandEvent_CommandFailed;       // 失败的命令
            DbWatch = null;
        }

        private  void CommandEvent_WillStart(object sender, CommandEventArgs e)
        {
            CadUnits.WriteMessage("\n开始的命令是:" + e.GlobalCommandName);
        }
        private void CommandEvent_CommandEnd(object sender, CommandEventArgs e)
        {
            CadUnits.WriteMessage("\n结束的命令是:" + e.GlobalCommandName);
        }
        private void CommandEvent_CommandCancelled(object sender, CommandEventArgs e)
        {
            CadUnits.WriteMessage("\n取消的命令是:" + e.GlobalCommandName);
        }
        private void CommandEvent_CommandFailed(object sender, CommandEventArgs e)
        {
            CadUnits.WriteMessage("\n失败的命令是:" + e.GlobalCommandName);
        }
        public void ActiveDoc()
        {

        }
    }

}
